package org.jmeter.tcp.helmet.protobuf.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.protobuf.GeneratedMessage;
import org.jmeter.tcp.helmet.protobuf.Common;
import org.jmeter.tcp.helmet.protobuf.HelmetServer;
import org.jmeter.tcp.helmet.protobuf.MessageId;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author liangsu
 * @version v1.0
 * @Description
 * @Date 2020/11/17 10:21
 * @since
 */
public class Helmet2ServerMsgBuilder {

    private static List<MsgDes> msgDesList = new ArrayList<MsgDes>();
    private static Map<String, MsgDes> msgTypeMap = new HashMap<String, MsgDes>();
    private static List<String> msgTypes = new ArrayList<String>();

    static {
        msgDesList.add(new MsgDes(MessageId.MsgId.H2S_MessageId_Register, Common.DeviceInfo.class,
                "register"));
        msgDesList.add(new MsgDes(MessageId.MsgId.H2S_MessageId_Heart_Beat, HelmetServer.H2SHeartBeat.class,
                "heartBeat"));
        msgDesList.add(new MsgDes(MessageId.MsgId.H2S_MessageId_Send_Voice, Common.VoiceData.class,
                "voiceData"));
        msgDesList.add(new MsgDes(MessageId.MsgId.H2S_MessageId_Req_Talk, HelmetServer.H2SRequestTalk.class,
                "requestTalk"));
        msgDesList.add(new MsgDes(MessageId.MsgId.H2S_MessageId_Sos, HelmetServer.H2SSos.class,
                "sos"));
        msgDesList.add(new MsgDes(MessageId.MsgId.H2S_MessageId_Version_Check, Common.SoftwareVersion.class,
                "versionCheck"));
        msgDesList.add(new MsgDes(MessageId.MsgId.H2S_MessageId_Start_Video, HelmetServer.H2SStartVideo.class,
                "startVideo"));
        msgDesList.add(new MsgDes(MessageId.MsgId.H2S_MessageId_Stop_Video, HelmetServer.S2HServerStopVideoResp.class,
                "serverStopVideoResp"));
        msgDesList.add(new MsgDes(MessageId.MsgId.H2S_MessageId_Fall_Detection, HelmetServer.H2SFallDetection.class,
                "fallDetection"));
        msgDesList.add(new MsgDes(MessageId.MsgId.H2S_MessageId_update_status, Common.DeviceStatus.class,
                "deviceStatus"));
        msgDesList.add(new MsgDes(MessageId.MsgId.H2S_MessageId_Refresh_Helmet_Voice, HelmetServer.H2SRefreshHelmetVoice.class,
                "refreshHelmetVoice"));
        msgDesList.add(new MsgDes(MessageId.MsgId.H2S_MessageId_Wear_Status, HelmetServer.H2SWearStatus.class,
                "wearStatus"));
//        msgDesList.add(new MsgDes(MessageId.MsgId.H2S_MessageId_End, Common.DeviceInfo.class,
//                "register"));



        //
        msgDesList.forEach(msgDes -> {
            msgTypeMap.put(msgDes.fieldName, msgDes);
            msgTypes.add(msgDes.fieldName);
            initMsgDes(msgDes);
        });
    }

    public static List<String> getMsgTypes() {
        return msgTypes;
    }

    private static void initMsgDes(MsgDes msgDes) {
        if(msgDes.method != null){
            return;
        }

        Method[] methods = HelmetServer.H2SMessage.Builder.class.getDeclaredMethods();
        for (Method method : methods) {
            if(!method.getName().startsWith("set")){
                continue;
            }

            String fieldName = BuilderUtils.getFiledNameBySetter(method);

            Class<?>[] parameterTypes = method.getParameterTypes();
            if(parameterTypes.length != 1){
                continue;
            }

//            System.out.println(method + ":" +fieldName);

            if(fieldName.equalsIgnoreCase(msgDes.fieldName)
                    && !parameterTypes[0].getName().endsWith("$Builder")){
                msgDes.method = method;
                break;
            }
        }
    }

    public static HelmetServer.H2SMessage buildHelmet2ServerMsg(String msgType, String version, String devId, String msg){
        MsgDes msgDes = msgTypeMap.get(msgType);

        // 构建消息类型
        JSONObject json = JSON.parseObject(msg);
        GeneratedMessage.Builder builder = BuilderUtils.build(msgDes.msgClass, json, "");

        // 封装安全帽到服务端的消息
        HelmetServer.H2SMessage.Builder h2sMsgBuilder = HelmetServer.H2SMessage.newBuilder();
        h2sMsgBuilder.setMsgid(msgDes.msgId);
        h2sMsgBuilder.setVersion(version);
        h2sMsgBuilder.setDevid(devId);

        //
        try {
//        h2sMsgBuilder.setRegister((Common.DeviceInfo)builder.build());
            msgDes.method.invoke(h2sMsgBuilder, builder.build());
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        // 构建消息体
        return h2sMsgBuilder.build();
    }

}

class MsgDes{
    MessageId.MsgId msgId;
    Class<?> msgClass;
    String fieldName;
    Method method;

    public MsgDes(MessageId.MsgId msgId, Class<?> msgClass, String fieldName) {
        this.msgId = msgId;
        this.msgClass = msgClass;
        this.fieldName = fieldName;
    }
}
